package xyz.yuzegod.megawalls.classes;

import com.google.gson.JsonElement;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import xyz.yuzegod.megawalls.MegaWalls;
import xyz.yuzegod.megawalls.classes.mythic.mole.Mole;
import xyz.yuzegod.megawalls.classes.mythic.phoenix.Phoenix;
import xyz.yuzegod.megawalls.classes.mythic.werewolf.Werewolf;
import xyz.yuzegod.megawalls.classes.normal.arcane.Arcane;
import xyz.yuzegod.megawalls.classes.normal.blaze.Blaze;
import xyz.yuzegod.megawalls.classes.normal.cow.Cow;
import xyz.yuzegod.megawalls.classes.normal.creeper.Creeper;
import xyz.yuzegod.megawalls.classes.normal.dreadlord.Dreadlord;
import xyz.yuzegod.megawalls.classes.normal.hunter.Hunter;
import xyz.yuzegod.megawalls.classes.normal.pigman.Pigman;
import xyz.yuzegod.megawalls.classes.normal.pirate.Pirate;
import xyz.yuzegod.megawalls.classes.normal.puppet.Puppet;
import xyz.yuzegod.megawalls.classes.normal.shaman.Shaman;
import xyz.yuzegod.megawalls.classes.normal.spider.Spider;
import xyz.yuzegod.megawalls.classes.normal.squid.Squid;
import xyz.yuzegod.megawalls.classes.novice.enderman.Enderman;
import xyz.yuzegod.megawalls.classes.novice.him.HIM;
import xyz.yuzegod.megawalls.classes.novice.skeleton.Skeleton;
import xyz.yuzegod.megawalls.classes.novice.zombie.Zombie;
import xyz.yuzegod.megawalls.game.GamePlayer;
import xyz.yuzegod.megawalls.stats.KitStatsContainer;
import xyz.yuzegod.megawalls.util.ItemUtils;
import xyz.yuzegod.megawalls.util.ParticleEffect;

import java.util.*;

public class ClassesManager
{
    private static final List<Classes> classesList;
    private static boolean registered;
    
    public static Classes getClassesByName(final String ClassesName) {
        for (final Classes classes : ClassesManager.classesList) {
            if (classes.getName().equalsIgnoreCase(ClassesName)) {
                return classes;
            }
        }
        return null;
    }
    
    public static void registerClasses(final Classes classes) {
        ClassesManager.classesList.add(classes);
    }
    
    public static boolean registerAll() {
        if (ClassesManager.registered) {
            return false;
        }
        registerClasses(new HIM());
        registerClasses(new Zombie());
        registerClasses(new Enderman());
        registerClasses(new Skeleton());
        registerClasses(new Shaman());
        registerClasses(new Puppet());
        registerClasses(new Spider());
        registerClasses(new Cow());
        registerClasses(new Pigman());
        registerClasses(new Squid());
        registerClasses(new Dreadlord());
        registerClasses(new Blaze());
        registerClasses(new Arcane());
        registerClasses(new Creeper());
        registerClasses(new Pirate());
        registerClasses(new Hunter());
        registerClasses(new Mole());
        registerClasses(new Werewolf());
        registerClasses(new Phoenix());
        return ClassesManager.registered = true;
    }
    
    public static void start() {
        ClassesManager.classesList.forEach(classes -> {
            Bukkit.getPluginManager().registerEvents((Listener)classes, (Plugin)MegaWalls.getInstance());
            Bukkit.getScheduler().runTaskTimer((Plugin)MegaWalls.getInstance(), classes, 0L, 20L);
        });
    }
    
    public static List<Classes> getNormalClasses() {
        final List<Classes> list = new ArrayList<Classes>();
        for (final Classes classes : ClassesManager.classesList) {
            if (classes.getClassesType() == ClassesType.NORMAL) {
                list.add(classes);
            }
        }
        return list;
    }
    
    public static List<Classes> getMythicClasses() {
        final List<Classes> list = new ArrayList<Classes>();
        for (final Classes classes : ClassesManager.classesList) {
            if (classes.getClassesType() == ClassesType.MYTHIC) {
                list.add(classes);
            }
        }
        return list;
    }
    
    public static List<Classes> getClasses() {
        return ClassesManager.classesList;
    }
    
    public static List<Classes> sort(final List<Classes> list) {
        Collections.sort(list, new Comparator<Classes>() {
            @Override
            public int compare(final Classes classes1, final Classes classes2) {
                if (classes1.getClassesType() == classes2.getClassesType()) {
                    return classes1.getDifficulty().getPriority() - classes2.getDifficulty().getPriority();
                }
                return classes1.getClassesType().getPriority() - classes2.getClassesType().getPriority();
            }
        });
        return list;
    }
    
    public static Classes getSelected(final GamePlayer gamePlayer) {
        final Classes cached = gamePlayer.getPlayerStats().getCacheSelected();
        return (cached == null) ? gamePlayer.getPlayerStats().getSelected() : cached;
    }
    
    public static boolean isClassesItem(final ItemStack itemStack) {
        if (itemStack.hasItemMeta() && itemStack.getItemMeta().getDisplayName() != null) {
            final String displayname = itemStack.getItemMeta().getDisplayName();
            return displayname.contains("剑") || displayname.contains("弓") || displayname.contains("镐") || displayname.contains("斧") || displayname.contains("锹") || displayname.contains("牛排") || displayname.contains("末影箱") || displayname.contains("头盔") || displayname.contains("胸甲") || displayname.contains("护腿") || displayname.contains("靴子") || displayname.contains("药水") || displayname.contains("箭") || displayname.contains("指南针") || displayname.contains("面包") || displayname.contains("鲑鱼") || displayname.contains("钓竿") || displayname.contains("金苹果");
        }
        return false;
    }
    
    public static void playSkillEffect(final Player player) {
        new BukkitRunnable() {
            double height;
            int ticks;
            
            public void run() {
                if (!player.isOnline() || this.ticks >= 8) {
                    this.cancel();
                    return;
                }
                for (int degree = 0; degree < 360; ++degree) {
                    final Location location = player.getLocation().clone();
                    final double radians = Math.toRadians(degree);
                    final double x = Math.cos(radians) + this.ticks;
                    final double z = Math.sin(radians) + this.ticks;
                    ParticleEffect.FLAME.display(0.0f, 0.0f, 0.0f, 0.0f, 1, location.clone().add(x, 0.0, z).add(0.0, this.height, 0.0), 30.0);
                }
                ++this.height;
                ++this.ticks;
            }
        }.runTaskTimer((Plugin)MegaWalls.getInstance(), 0L, 1L);
    }
    
    public static void giveItems(final GamePlayer gamePlayer) {
        final Player player = gamePlayer.getPlayer();
        final KitStatsContainer kitStats = gamePlayer.getPlayerStats().getKitStats(gamePlayer.getPlayerStats().getSelected());
        final int level = kitStats.getEquipLevel();
        if (kitStats.getInventory() == null) {
            for (final ItemStack itemStack : gamePlayer.getPlayerStats().getSelected().getEquipmentPackage().getEquipments(level)) {
                if (ItemUtils.isHelmet(itemStack)) {
                    player.getInventory().setHelmet(itemStack);
                }
                else if (ItemUtils.isChestplate(itemStack)) {
                    player.getInventory().setChestplate(itemStack);
                }
                else if (ItemUtils.isLeggings(itemStack)) {
                    player.getInventory().setLeggings(itemStack);
                }
                else if (ItemUtils.isBoots(itemStack)) {
                    player.getInventory().setBoots(itemStack);
                }
                else {
                    player.getInventory().addItem(new ItemStack[] { itemStack });
                }
            }
        }
        else {
            for (final Map.Entry<String, JsonElement> entry : kitStats.getInventory().entrySet()) {
                final int slot = Integer.parseInt(entry.getKey());
                player.getInventory().setItem(slot, ItemUtils.read(Base64.decode(entry.getValue().getAsString())));
            }
            for (final ItemStack itemStack : gamePlayer.getPlayerStats().getSelected().getEquipmentPackage().getEquipments(level)) {
                if (ItemUtils.isHelmet(itemStack)) {
                    player.getInventory().setHelmet(itemStack);
                }
                else if (ItemUtils.isChestplate(itemStack)) {
                    player.getInventory().setChestplate(itemStack);
                }
                else if (ItemUtils.isLeggings(itemStack)) {
                    player.getInventory().setLeggings(itemStack);
                }
                else {
                    if (!ItemUtils.isBoots(itemStack)) {
                        continue;
                    }
                    player.getInventory().setBoots(itemStack);
                }
            }
        }
    }
    
    static {
        classesList = new ArrayList<Classes>();
        ClassesManager.registered = false;
    }
}
